package com.jiajunsong.blog.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.filter.OncePerRequestFilter;

import com.jiajunsong.blog.controller.ValidateCodeController;
import com.jiajunsong.blog.domain.ValidateCode;
import com.jiajunsong.blog.domain.ValidateCodeException;

//@Component
public class ValidateCodeFilter extends OncePerRequestFilter {
	@Autowired
	private AuthenticationFailureHandler authenticationFailureHandler;
	private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		if (StringUtils.equals("/login", request.getRequestURI())
						&& StringUtils.equalsIgnoreCase("post", request.getMethod())) {
			try {
				validate(new ServletWebRequest(request),ValidateCodeController.IMAGE_CODE_IN_SESSION);
			} catch (ValidateCodeException e) {
				authenticationFailureHandler.onAuthenticationFailure(request, response, e);
				return;
			}
		}
		
		if (StringUtils.equals("/authentication/sms", request.getRequestURI())
						&& StringUtils.equalsIgnoreCase("post", request.getMethod())) {
			try {
				validate(new ServletWebRequest(request),ValidateCodeController.SMS_CODE_IN_SESSION);
			} catch (ValidateCodeException e) {
				authenticationFailureHandler.onAuthenticationFailure(request, response, e);
				return;
			}
		}

		filterChain.doFilter(request, response);

	}

	private void validate(ServletWebRequest servletWebRequest,String CODE_IN_SESSION) {
		// TODO Auto-generated method stub
		ValidateCode codeInSession = (ValidateCode) sessionStrategy.getAttribute(servletWebRequest,
				CODE_IN_SESSION);
		sessionStrategy.removeAttribute(servletWebRequest, CODE_IN_SESSION);
		String codeInRequest="";
		try {
			codeInRequest = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(), "code");
		} catch (ServletRequestBindingException e) {
			// TODO Auto-generated catch block
			throw new ValidateCodeException("从请求中获取验证码的值失败");
		}
		if (StringUtils.isBlank(codeInRequest)) {
			throw new ValidateCodeException("验证码的值不能为空");
		}
		if (codeInSession == null) {
			throw new ValidateCodeException("验证码在session中不存在");
		}

		if (codeInSession.isExpried()) {
			throw new ValidateCodeException("验证码已过期,请重新生成一个验证码");
		}

		if (!StringUtils.equals(codeInSession.getCode(), codeInRequest)) {
			throw new ValidateCodeException("验证码不匹配");
		}
	}

}
